import { cn } from "@/lib/utils";
import { ClassValue } from "clsx";
import { useState } from "react";
import { FaAngleRight } from "react-icons/fa6";
export { Tree, TreeNode, TreeNodeProp, TreeProp };

type TreeProp<T> = {
	data: T[],
	getId: (v: T) => string
	getTitle: (v: T) => string
	getParentId: (v: T) => string | null
	onSelected?: (v: T) => void
} & React.HTMLAttributes<HTMLDivElement>;

function Tree<T>(props: TreeProp<T>) {
	const { data, getId, getParentId, ...rest } = props;
	const [map] = useState(() => {
		const map: Record<string, T[]> = {}
		for (const item of data) {
			const parentId = getParentId(item) || ''
			const children = map[parentId] || []
			children.push(item)
			map[parentId] = children
		}
		return map
	})
	const roots = map[''] || []
	return (
		<div {...rest}>
			{roots.map(root => (
				<TreeNode
					key={getId(root)}
					value={root}
					map={map}
					{...props}
				/>
			))}
		</div>
	)
}

type TreeNodeProp<T> = { value: T, map: Record<string, T[]> } & TreeProp<T>

function TreeNode<T>(props: TreeNodeProp<T>) {
	const { value, map, getId, getTitle } = props;
	const children = map[getId(value)]
	const hasChildren = children?.length > 0
	const [expand, setExpand] = useState(false)

	const onSelect = (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
		e.stopPropagation()
		setExpand(!expand)
		props.onSelected?.(value)
	}

	return (
		<>
			<div
				onClick={onSelect}
				className="flex justify-between items-center
				hover:bg-stone-100 px-2 rounded-md cursor-pointer"
			>
				{getTitle(value)}
				{hasChildren && (
					<div  >
						<FaAngleRight />
					</div>
				)}
			</div>

			<div
				className="pl-4"
			>
				{hasChildren && expand && (
					children.map(child => (
						<TreeNode key={getId(child)}  {...props} value={child} map={map} />
					))
				)}
			</div>
		</ >
	)
}